﻿namespace DotNetCommon.Extensions
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text.Json.Nodes;
    using System.Xml.Linq;

    /// <summary>
    /// <see cref="IList{T}"/> 的扩展方法
    /// </summary>
    public static class ListExtensions
    {
        /// <summary>
        /// 主要用来做List的初始化: <code>new List&lt;int>{1,new int[]{2,3},4}</code>
        /// </summary>
        /// <returns>返回自身</returns>
        public static IList<T> Add<T>(this IList<T> list, IEnumerable<T> items)
        {
            if (list == null) return list;
            foreach (var item in items)
            {
                list.Add(item);
            }
            return list;
        }

        /// <summary>
        /// 将给定的<paramref name="items"/>添加到给定的<paramref name="list"/>。
        /// </summary>
        /// <returns>返回自身</returns>
        public static IList<T> AddRange<T>(this IList<T> list, IEnumerable<T> items)
        {
            if (list == null) return list;
            foreach (var item in items)
            {
                list.Add(item);
            }
            return list;
        }

        /// <summary>
        /// 从指定的集合中移除符合条件的元素
        /// </summary>
        /// <returns>返回自身</returns>
        public static IList<T> Remove<T>(this IList<T> list, Func<T, bool> predicate)
        {
            if (list == null) return list;
            list.Where(predicate).ToList().ForEach(t =>
            {
                if (list.Contains(t)) list.Remove(t);
            });
            return list;
        }

        #region Fluent风格 List<T> IList<T> AddFluent AddRangeFluent ClearFluent RemoveAtFluent InsertAtFluent
        /// <summary>
        /// Fluent风格: 向集合中添加新项,并返回自身
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static List<T> AddFluent<T>(this List<T> list, T item)
        {
            list.Add(item);
            return list;
        }

        /// <summary>
        /// Fluent风格: 向集合中添加新项,并返回自身
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static IList<T> AddFluent<T>(this IList<T> list, T item)
        {
            list.Add(item);
            return list;
        }

        /// <summary>
        /// Fluent风格: 向集合中添加新项集合,并返回自身
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static List<T> AddRangeFluent<T>(this List<T> list, IEnumerable<T> items)
        {
            if (items.IsNullOrEmpty()) return list;
            foreach (var item in items) list.Add(item);
            return list;
        }

        /// <summary>
        /// Fluent风格: 向集合中添加新项集合,并返回自身
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static IList<T> AddRangeFluent<T>(this IList<T> list, IEnumerable<T> items)
        {
            if (items.IsNullOrEmpty()) return list;
            foreach (var item in items) list.Add(item);
            return list;
        }

        /// <summary>
        /// Fluent风格: 清空集合并返回自身
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static List<T> ClearFluent<T>(this List<T> list)
        {
            list.Clear();
            return list;
        }

        /// <summary>
        /// Fluent风格: 清空集合并返回自身
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static IList<T> ClearFluent<T>(this IList<T> list)
        {
            list.Clear();
            return list;
        }

        /// <summary>
        /// Fluent风格: 从集合中移除某项
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static List<T> RemoveAtFluent<T>(this List<T> list, int index)
        {
            list.RemoveAt(index);
            return list;
        }

        /// <summary>
        /// Fluent风格: 从集合中移除某项
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static IList<T> RemoveAtFluent<T>(this IList<T> list, int index)
        {
            list.RemoveAt(index);
            return list;
        }

        /// <summary>
        /// Fluent风格: 向集合中插入某项
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static List<T> InsertAtFluent<T>(this List<T> list, int index, T b)
        {
            list.Insert(index, b);
            return list;
        }

        /// <summary>
        /// Fluent风格: 向集合中插入某项
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null,抛出异常</item>
        /// </list>
        /// </remarks>
        public static IList<T> InsertAtFluent<T>(this IList<T> list, int index, T b)
        {
            list.Insert(index, b);
            return list;
        }

        /// <summary>
        /// Fluent风格: 设置集合中指定索引的值
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null或索引超出,抛出异常</item>
        /// </list>
        /// </remarks>
        public static IList<T> SetFluent<T>(this IList<T> list, int index, T b)
        {
            list[index] = b;
            return list;
        }

        /// <summary>
        /// Fluent风格: 设置集合中指定索引的值
        /// </summary>
        /// <remarks>
        /// 注意:
        /// <list type="bullet">
        /// <item>如果集合为null或索引超出,抛出异常</item>
        /// </list>
        /// </remarks>
        public static List<T> SetFluent<T>(this List<T> list, int index, T b)
        {
            list[index] = b;
            return list;
        }
        #endregion
    }
}